
package com.naza.rpc.netty;

import com.google.common.reflect.Reflection;
import com.naza.rpc.consumer.balance.manage.ClientManage;
import com.naza.rpc.serialize.RpcSerializeProtocol;

import java.util.List;
import java.util.Set;

/**
 * RPC调用客户端执行模块  单例
 * 实际是动态代理了MessageSendProxy，使用了jdk原生的动态代理实现，也可以改成CGLIB。
 * 
 * @author yl
 */
public class RpcSendExecutor {

    private static ClientManage clientManage = ClientManage.INSTANCE;

    private RpcSerializeProtocol protocol;

    private static class MessageSendExecutorHolder {
        private static final RpcSendExecutor INSTANCE = new RpcSendExecutor();
    }

    public static RpcSendExecutor getInstance() {
        return MessageSendExecutorHolder.INSTANCE;
    }

    public RpcSerializeProtocol getProtocol(){
        return protocol;
    }

    private RpcServerLoader loader = RpcServerLoader.getInstance();

    private RpcSendExecutor() {

    }

/*    public RpcSendExecutor(String serverAddress, RpcSerializeProtocol serializeProtocol) {
        loader.load(serverAddress, serializeProtocol);
    }*/

    public void setRpcServerLoader(RpcSerializeProtocol serializeProtocol) {
        this.protocol = serializeProtocol;
        //loader.load(providers, serializeProtocol);
    }

    public void startConnect(String serviceName){
        loader.load(clientManage,serviceName,protocol);
    }

    public void stopConnect(String serviceAddr){
        loader.stopConnectTask(serviceAddr);
    }

    public void stopConnect(Set<String> serviceAddrs){
        for(String serviceAddr : serviceAddrs){
            loader.stopConnectTask(serviceAddr);
        }
    }

    public void stop() {
        loader.unLoad();
    }

    /**
     * 向服务端发送消息，jdk原生动态代理了 RpcSendProxy，使用MessageSendProxy的handleInvocation发送消息
     * @param rpcInterface
     * @return
     * @throws Exception
     */
    public <T> T execute(Class<T> rpcInterface) throws Exception {
        System.out.println("send message to server.");
        clientManage.addService(rpcInterface.getName());
        clientManage.monitor(rpcInterface.getName());
        return (T) Reflection.newProxy(rpcInterface, new RpcSendProxy<T>());
    }
}
